/*
 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.io;

/**
 * <code>FilterInputStream</code>包含其他输入流，
 * 将其用作基本数据源，可能在此过程中转换数据或提供附加功能。
 * <code>FilterInputStream</code>类本身只是用将所有请求传递给
 * 包含的输入流的版本覆盖<code>InputStream</code>的所有方法。
 * <code>FilterInputStream</code>的子类可以进一步覆盖其中一些方法，
 * 也可以提供附加的方法和字段。
 *
 * @author  Jonathan Payne
 * @since   JDK1.0
 */
public
class FilterInputStream extends InputStream {
    /**
     * 要过滤的输入流。
     */
    protected volatile InputStream in;

    /**
     * 通过将参数<code>in</code>分配给字段<code>this.in</code>
     * 来创建<code>FilterInputStream</code>，以便记住它供以后使用。
     *
     * @param   in   底层输入流，如果要创建没有底层流的实例，则为<code>null</code>。
     */
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }

    /**
     * 从此输入流读取下一个数据字节。值字节作为<code>0</code>到<code>255</code>
     * 范围内的<code>int</code>返回。如果由于已到达流的末尾而没有可用字节，
     * 则返回值<code>-1</code>。此方法会阻塞，直到输入数据可用、检测到流的末尾
     * 或抛出异常。
     * <p>
     * 此方法只是执行<code>in.read()</code>并返回结果。
     *
     * @return     下一个数据字节，如果到达流的末尾则返回<code>-1</code>。
     * @exception  IOException  如果发生I/O错误。
     * @see        java.io.FilterInputStream#in
     */
    public int read() throws IOException {
        return in.read();
    }

    /**
     * 从此输入流读取最多<code>byte.length</code>字节的数据到字节数组中。
     * 此方法会阻塞，直到某些输入可用。
     * <p>
     * 此方法只是执行调用<code>read(b, 0, b.length)</code>并返回结果。
     * 重要的是它<i>不</i>执行<code>in.read(b)</code>；
     * <code>FilterInputStream</code>的某些子类依赖于实际使用的实现策略。
     *
     * @param      b   读取数据的缓冲区。
     * @return     读取到缓冲区的总字节数，如果由于到达流的末尾而没有更多数据，
     *             则返回<code>-1</code>。
     * @exception  IOException  如果发生I/O错误。
     * @see        java.io.FilterInputStream#read(byte[], int, int)
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    /**
     * 从此输入流读取最多<code>len</code>字节的数据到字节数组中。
     * 如果<code>len</code>不为零，该方法会阻塞，直到某些输入可用；
     * 否则，不读取任何字节并返回<code>0</code>。
     * <p>
     * 此方法只是执行<code>in.read(b, off, len)</code>并返回结果。
     *
     * @param      b     读取数据的缓冲区。
     * @param      off   目标数组<code>b</code>中的起始偏移量
     * @param      len   读取的最大字节数。
     * @return     读取到缓冲区的总字节数，如果由于到达流的末尾而没有更多数据，
     *             则返回<code>-1</code>。
     * @exception  NullPointerException 如果<code>b</code>为<code>null</code>。
     * @exception  IndexOutOfBoundsException 如果<code>off</code>为负数，
     * <code>len</code>为负数，或<code>len</code>大于<code>b.length - off</code>
     * @exception  IOException  如果发生I/O错误。
     * @see        java.io.FilterInputStream#in
     */
    public int read(byte b[], int off, int len) throws IOException {
        return in.read(b, off, len);
    }

    /**
     * 跳过并丢弃输入流中的<code>n</code>字节数据。由于各种原因，
     * <code>skip</code>方法可能最终跳过较少的字节数，可能为<code>0</code>。
     * 返回实际跳过的字节数。
     * <p>
     * 此方法只是执行<code>in.skip(n)</code>。
     *
     * @param      n   要跳过的字节数。
     * @return     实际跳过的字节数。
     * @exception  IOException  如果流不支持查找，或发生其他I/O错误。
     */
    public long skip(long n) throws IOException {
        return in.skip(n);
    }

    /**
     * 返回可以从此输入流读取（或跳过）而不被此输入流方法的下一个调用者阻塞的
     * 字节数的估计值。下一个调用者可能是同一线程或另一个线程。
     * 单次读取或跳过这么多字节不会阻塞，但可能读取或跳过较少的字节。
     * <p>
     * 此方法返回{@link #in in}.available()的结果。
     *
     * @return     可以从此输入流读取（或跳过）而不阻塞的字节数的估计值。
     * @exception  IOException  如果发生I/O错误。
     */
    public int available() throws IOException {
        return in.available();
    }

    /**
     * 关闭此输入流并释放与该流关联的任何系统资源。
     * 此方法只是执行<code>in.close()</code>。
     *
     * @exception  IOException  如果发生I/O错误。
     * @see        java.io.FilterInputStream#in
     */
    public void close() throws IOException {
        in.close();
    }

    /**
     * 标记此输入流中的当前位置。随后调用<code>reset</code>方法会将此流
     * 重新定位到最后标记的位置，以便后续读取重新读取相同的字节。
     * <p>
     * <code>readlimit</code>参数告诉此输入流在标记位置失效之前
     * 允许读取那么多字节。
     * <p>
     * 此方法只是执行<code>in.mark(readlimit)</code>。
     *
     * @param   readlimit   在标记位置变为无效之前可以读取的字节的最大限制。
     * @see     java.io.FilterInputStream#in
     * @see     java.io.FilterInputStream#reset()
     */
    public synchronized void mark(int readlimit) {
        in.mark(readlimit);
    }

    /**
     * 将此流重新定位到上次在此输入流上调用<code>mark</code>方法时的位置。
     * <p>
     * 此方法只是执行<code>in.reset()</code>。
     * <p>
     * 流标记旨在用于需要提前读取一点以查看流中内容的情况。
     * 通常，这最容易通过调用某个通用解析器来完成。如果流是解析器处理的类型，
     * 它就会愉快地继续运行。如果流不是那种类型，解析器应该在失败时抛出异常。
     * 如果这发生在readlimit字节内，它允许外部代码重置流并尝试另一个解析器。
     *
     * @exception  IOException  如果流尚未标记或标记已失效。
     * @see        java.io.FilterInputStream#in
     * @see        java.io.FilterInputStream#mark(int)
     */
    public synchronized void reset() throws IOException {
        in.reset();
    }

    /**
     * 测试此输入流是否支持<code>mark</code>和<code>reset</code>方法。
     * 此方法只是执行<code>in.markSupported()</code>。
     *
     * @return  如果此流类型支持<code>mark</code>和<code>reset</code>方法，
     *          则返回<code>true</code>；否则返回<code>false</code>。
     * @see     java.io.FilterInputStream#in
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.InputStream#reset()
     */
    public boolean markSupported() {
        return in.markSupported();
    }
}
